<!--
 * @Description: 登录界面
-->
<template>
  <div class="login sign_in">
    <div class="card-wrapper">
      <div class="left">
        <div v-if="openFace" class="face-login">
          <el-button @click="openAndInitCamera()">摄像头</el-button>
          <el-button @click="openAndUploadImg()">图片</el-button>
          <div v-if="openCamera" class="face-camera">
            <div>
              <canvas ref="canvasElement"></canvas>
              <video ref="videoElement" autoplay></video>
            </div>
            <el-button @click="takePhoto">拍照</el-button>
            <el-button @click="submitFace('camera')">提交</el-button>
          </div>
		  <div v-if="openFaceImg" class="face-img">
		    <el-upload
		      id="photo"
		      class="avatar-uploader"
		      drag
		      accept="image/gif, image/jpeg, image/png, image/jpg"
		      action=""
		      :http-request="uploadImg"
		      :show-file-list="false"
		    >
		      <img
		        v-if="ruleForm['face_image']"
		        :src="$fullUrl($banseUrl, ruleForm.face_image)"
		        class="avatar"
		        style="width: 100%; height: 100%"
		      />
		      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
		    </el-upload>
		    <el-button @click="submitFace('img')">提交</el-button>
		  </div>
        </div>
      </div>
      <div class="right">
        <div class="title">样式开发测试测试测试测试单</div>
        <el-form
          class="login-form"
          ref="ruleFormRef"
          label-width="120px"
          :label-position="'top'"
          :model="ruleForm"
          :rules="rules"
        >
          <el-form-item label="用户名" prop="username">
            <el-input
              @keyup.enter="buttonLogin"
              size="large"
              class="input"
              v-model="ruleForm.username"
              prefix-icon="User"
              placeholder="请输入用户名"
            >
            </el-input>
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input
              @keyup.enter="buttonLogin"
              size="large"
              class="input"
              v-model="ruleForm.password"
              prefix-icon="Lock"
              type="password"
              placeholder="请输入密码"
            >
            </el-input>
          </el-form-item>
          <!-- 数字验证开始 -->
          <div class="geetest_box">
            <div class="geetest_box_title">验证</div>
            <div class="geetest_box_content">
              <Verification ref="child"></Verification>
            </div>
          </div>
          <!-- 数字验证结束 -->
        </el-form>
        <div class="button-wrapper">
          <el-button class="btn_login" type="primary" @click="buttonLogin">登录</el-button>
          <el-button
            class="btn_register"
            type="primary"
            @click="router.push('/register')"
          >
            注册
          </el-button>
          <el-button
            class="forgot_nav"
            type="primary"
            @click="router.push('/forgot')"
          >
            <span>找回密码</span>
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { rsaEncrypt } from "@/store/encrypt";
import Identify from "./Identify.vue";
import { $post, $get } from "@/api/Api.js";
import {
  $get_auth,
  func,
  $fullUrl,
  $banseUrl,
} from "@/utils/utils.js";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { reactive, ref, computed, onMounted, getCurrentInstance } from "vue";
import storageHelper from "@/libs/StorageHelper";
const { appContext } = getCurrentInstance();
appContext.config.globalProperties.$loadExternalScript();
let router = useRouter();
let store = useStore();
let user_set = (payload) => store.commit("userStoreModule/user_set", payload);
let set_auth = (payload) => store.commit("web/set_auth", payload);
let ruleFormRef = ref(null);
let identifyState = ref(false);
let url_upload = ref("/api/user/upload");
let openFace = ref(false);
let openCamera = ref(false);
let openFaceImg = ref(false);
let cameraPhotoUrl = ref(null);
let ruleForm = ref({
  username: "",
  password: "",
  face_image: "",
  pictureCode: "", //输入input框的验证码
  identifyCode: "", //存储的图片验证码
});

let rules = ref({
  username: [
    {
      required: true,
      message: "请输入用户名",
      trigger: "blur",
    },
  ],
  password: [
    {
      required: true,
      message: "请输入密码",
      trigger: "blur",
    },
  ],
  pictureCode: [
    {
      required: true,
      message: "请输入验证码",
      trigger: "blur",
    },
  ],
});
let child = ref(null);
// 获取随机图片验证码
let refreshCode = () => {
  ruleForm.value.pictureCode = "";
  let numCode = "";
  for (var i = 0; i < 4; i++) {
    numCode += Math.floor(Math.random() * 10);
  }
  ruleForm.value.identifyCode = numCode;
};

let videoElement = ref(null);
let canvasElement = ref(null);
let buttonLogin = async () => {
  const bool = child.value.Childsublim();
  if(!bool){
  	return
  }
  let valid = await ruleFormRef.value.validate();
  if (valid) {
    var form = Object.assign({}, ruleForm.value);
    form.password = rsaEncrypt(form.password);
    form.is_face = "face";
    $post("/api/user/login?", form).then((res) => {
      if (res.result && res.result.obj) {
        openFace.value = true;
      } else if (res.error) {
        console.log(res.error);
        ElMessage.error(res.error.message);
      }
    });
  }
};
/**
 * 上传文件
 * @param {String} url 请求地址
 * @param {Object} body 请求参数
 * @param {Funciton} func 回调函数，可以为空，为空则采用await返回值
 * @return {Object} 返回请求结果
 */
let $upload = async (url, body, fun) => {
  url = url.replace("~/", $banseUrl);

  //let token = this.$store.state.user.token || $.db.get("token") || null;
  let token = null;
  if (fun) {
    // 如果回调函数存在, 则采用异步
    await $post(url, body, {
      headers: {
        "x-auth-token": token,
        "Content-Type": "multipart/form-data",
      },
    })
      .then((res) => {
        fun(res);
      })
      .catch((res) => {
        console.log(res);
        // fun(res);
      });
  } else {
    // 否则采用同步
    let res = await $post(url, body, {
      headers: {
        "x-auth-token": token,
        "Content-Type": "multipart/form-data",
      },
    }).then((res) => {
      return res;
    });
  }
};

/**
 * 上传文件
 * @param {Object} file 文件对象
 * @param {key} 保存键名
 */
let uploadFile = async (file, key = "img", url_upload) => {
  let form = new FormData(); // FormData 对象
  form.append("file", file); // 文件对象
  let url = url_upload.replace("~/", $banseUrl);
  let tokenVa = computed(() => store.state.userStoreModule.token);
  let token = tokenVa || storageHelper.getToken() || null;
  $upload(url_upload, form, function (json) {
    if (json.result) {
      if (typeof ruleForm.value.face_image != "undefined") {
        ruleForm.value.face_image = json.result.url;
      }
    } else {
      ElMessage.error("上传失败！");
    }
  });
};
let initCamera = () => {
  navigator.mediaDevices
    .getUserMedia({ video: true })
    .then((stream) => {
      const videoElement = videoElement.value;
      videoElement.srcObject = stream;
      videoElement.play();
    })
    .catch((error) => {
      console.error("无法访问摄像头：", error);
    });
};
let takePhoto = () => {
  const videoElement = videoElement.value;
  const canvasElement = canvasElement.value;
  const context = canvasElement.getContext("2d");
  // 将视频流的画面绘制到Canvas中
  context.drawImage(
    videoElement,
    0,
    0,
    canvasElement.width,
    canvasElement.height
  );

  // 获取Canvas中的图像数据
  const imageData = canvasElement.toDataURL("image/png");

  // 显示拍摄的照片
  cameraPhotoUrl.value = imageData;

  let file = base64ToFile(cameraPhotoUrl.value, "cameraImg");

  uploadFile(file, "face_image", url_upload.value);
  // face_url.value=ruleForm.value.face_image
};
let closeVideo = () => {
  const srcObject = videoElement.value.srcObject
    ? videoElement.value.srcObject.getTracks()
    : videoElement.value.src.getTracks();
  srcObject.forEach((track) => {
    track.stop();
    videoElement.value.src = null;
  });
};
let uploadImg = (param) => {
  uploadFile(param.file, "face_image", url_upload.value);
};
let openAndInitCamera = () => {
  openFaceImg.value = false;
  openCamera.value = true;
  initCamera();
};
let openAndUploadImg = () => {
  openCamera.value = false;
  openFaceImg.value = true;
};
let submitFace = (type) => {
  if (type === "camera") {
    closeVideo();
  }
  //人脸识别登录
  let formObj = {
    username: ruleForm.value.username + "",
    face_image: ruleForm.value.face_image,
  };
  $post("/api/user/face_login?", formObj).then((res) => {
    if (res.result && res.result.obj) {
      var obj = res.result.obj;
      storageHelper.setToken(obj.token);
      $Getauth(obj.user_group);
      store.commit("userStoreModule/user_set", obj);
      ElMessage.success("登录成功！");
      // window.location.reload();
    } else if (res.error) {
      console.log(res.error);
      ElMessage.error(res.error.message);
    }
  });
};
//base64转flie
let base64ToFile = (base64, name) => {
  if (typeof base64 != "string") {
    return;
  }
  let arr = base64.split(",");
  let type = arr[0].match(/:(.*?);/)[1];
  let fileExt = type.split("/")[1];
  let bstr = atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new File([u8arr], `${name}.` + fileExt, {
    type: type,
  });
};
let $Getauth = (user_group) => {
  //查询权限
  $get("/api/auth/get_list?user_group=" + user_group).then((json) => {
    window.localStorage.setItem("set_auth", "");
    store.commit("web/set_auth", []);
    // 清空权限
    // store.commit("set_auth", []);
    // 判断查询结果
    if (json.result && json.result.list) {
      let auth = json.result.list;
      window.localStorage.setItem("set_auth", JSON.stringify(auth));
      store.commit("web/set_auth", auth);
      router.push("/home");
      // 权限缓存
    } else if (json.error) {
      ElMessage.error(json.error.message);
      console.error(json.error);
    }
  });
};
onMounted(() => {
  refreshCode();
});
</script>

<style lang="less" scoped>
.login {
  position: relative;
  width: 100%;
  height: 100%;
  background-image: url("../../assets/images/bg.jpg");
  background-size: 100% 100%;
  .card-wrapper {
    z-index: 999;
    background: white;
    width: 900px;
    height: 460px;
    position: absolute;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    display: flex;
    margin: auto;
    .left {
      width: 400px;
      background-image: url("../../assets/images/bg.jpg");
    }
    .right {
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      align-items: center;

      .title {
        font-size: 34px;
        // color: #4caaa2;
      }
      .login-form {
        .input {
          width: 270px;
        }
      }
      .button-wrapper {
        text-align: center;
        .button {
          width: 270px;
        }
      }
    }
  }
  .face-img {
    width: 150px;
    height: 150px;
    margin: 0 auto;
    .el-upload-dragger {
    }
    img {
      width: 150px;
      height: 150px;
    }
  }
}
</style>

<style lang="less">
.login {
  .right {
    .pictureCode {
      .el-input-group__append {
        // height:100%;
      }
    }
  }
  .left {
    text-align: center;
    .el-upload-dragger {
      // height:100%;
    }
  }
}
.geetest_box_title{
	font-size: 14px;
	color: #606266;
	margin-bottom: 8px;
	    line-height: 22px;
}
.geetest_box_content{
	margin-left:13px;
}
.geetest_box .el-input__wrapper{
	line-height: 38px;
	height: 38px;
	padding: 1px 17px !important;
}
.geetest_box_title::before{
	content: "*";
	color: var(--el-color-danger);
	margin-right: 4px;
}
</style>
